#include <QTextCodec>
#include <QIcon>
#include <QModelIndex>

#include "nconfig.h"
#include "nmusicfile.h"
#include "nfilelistmodel.h"


NFileListModel::NFileListModel(){
   
#ifdef  N_PHONON
    isPlaying = false;
    isOpening = false;
    playingRow = -1;
    music = NULL;
#endif

    _encoding = 106;
}

NFileListModel::~NFileListModel(){
#ifdef  N_PHONON
    if(music)
	delete music;
#endif

    if(!records.empty()){
	QList<NMusicFile *>::iterator i;
	for(i = records.begin(); i != records.end(); ++i)
	    delete (* i);
    }
}

void NFileListModel::addFiles(const QStringList &filePaths){    
    if(filePaths.count() == 0) return;
        
#ifdef  N_PHONON
	if(records.size() == 0)
	    isOpening = true;
#endif

    beginInsertRows(QModelIndex(), rowCount(), rowCount() + filePaths.count() - 1);
	
    QStringList::const_iterator iter;
    for (iter = filePaths.constBegin();  iter != filePaths.constEnd(); ++iter){
	NMusicFile *file = NMusicFile::load((*iter));
    
	if(!file) continue;
        

	 records.append(file);
    }
    
    endInsertRows();
    
}

void NFileListModel::addFile(const QString &filePath){
    QStringList list(filePath);
    addFiles(list);
}

void NFileListModel::clear(){
#ifdef  N_PHONON
    if(music){
	music->stop();
	delete music;
	music = NULL;
    }
#endif

    beginRemoveRows(QModelIndex(), 0, rowCount() - 1);
    
    QList<NMusicFile *>::iterator i;
    for(i = records.begin(); i != records.end(); ++i)
	delete (* i);
    
    records.clear();    
    endRemoveRows();
}

int NFileListModel::encoding() const { return _encoding; }

int NFileListModel::recordsCount() const{
    return records.count();
}

void NFileListModel::setEncoding(const int x) { 
    if(_encoding == x) return;
    _encoding = x; 
    
    if(rowCount() < 1) return;
    
    emit dataChanged(index(0, 0), index(rowCount() - 1, columnCount() - 1));
}

void NFileListModel::saveAll(){
    QList<NMusicFile *>::iterator i;
    for(i = records.begin(); i != records.end(); ++i){
	NMusicFile *file = (* i);
	file->setEncoding(QTextCodec::codecForMib(_encoding));
	file->save();
    }
}

/* delegate methods */

int NFileListModel::rowCount ( const QModelIndex & parent ) const{
    Q_UNUSED(parent);
    return records.count();
}

int NFileListModel::columnCount ( const QModelIndex & parent ) const{
    Q_UNUSED(parent);
    return 4;
}

QVariant NFileListModel::data ( const QModelIndex & index, int role ) const{
    if (!index.isValid()) return QVariant();
    
    if (index.row() >= records.size() || index.row() < 0) return QVariant();
    
    NMusicFile *file = records.at(index.row());
    
    switch (role ) {
	case Qt::DisplayRole: 
	    
	file->setEncoding(QTextCodec::codecForMib(_encoding));

	if(index.column() == 0)
	    return file->name();
	else if(index.column() == 1)
	    return file->artist();
	else if(index.column() == 2)
	    return file->album();
	else if(index.column() == 3)
	    return file->path();	
	break;
	
#ifdef  N_PHONON
	case Qt::DecorationRole:
	    if(index.column() == 0)
		return index.row() != playingRow ? QIcon(":/images/play/ppause") : QIcon(":/images/play/pstart");
	    break;
#endif

	case Qt::ToolTipRole: 
	    if(index.column() == 3)
		return file->path();
	    break;
    } 
    
    return QVariant();
}

QVariant NFileListModel::headerData ( int section, Qt::Orientation orientation, int role ) const{
    if (role != Qt::DisplayRole) return QVariant();

    switch (orientation) {
	case  Qt::Horizontal:
	switch(section){
	    case 0:
		return tr("Name");
	    case 1:
		return tr("Artist");
	    case 2:
		return tr("Album");
	    case 3:
		return tr("Path");
	    default:
		return QVariant();
	}
	break;
	case Qt::Vertical:
	    return QVariant(section + 1);
    }

    return QVariant();
}

void NFileListModel::sSelectedRowChanged(const QModelIndex &cur, const QModelIndex &pre){
    Q_UNUSED(pre);
    
    if(cur.row() < 0 || cur.row() >= rowCount()) return;
    
    emit selectedSongChanged(records.at(cur.row()));
    
#ifdef  N_PHONON
    if(isOpening) {
	isOpening = false;
	return;
    }
    
    if(cur.column() != 0) {
	playingRow = -1;
	pausePlaying();
	return;
    }
    
    if(playingRow == cur.row()){
	if(isPlaying)
	    pausePlaying();
	else
	    startPlaying();
    } else {
	playingRow = cur.row();
	startPlaying();
    }    
#endif
}

/* private */


#ifdef  N_PHONON
void NFileListModel::startPlaying(){
    Q_ASSERT(playingRow != -1 && playingRow < records.size());
    
    QString path = records.at(playingRow)->path();
    
    if(music != NULL){
	music->stop();
	delete music;
	music = NULL;
    }
    
    music = Phonon::createPlayer(Phonon::MusicCategory,  Phonon::MediaSource(path));
    music->play();
    isPlaying = true;
}

void NFileListModel::pausePlaying(){
    if(music == NULL) return;
    
    music->pause();
    isPlaying = false;
}
#endif
